package com.foreveross.fetl.common.jpa;

import java.io.Serializable;
import java.util.List;

import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Repository;

import com.foreveross.fetl.common.domain.IBaseEntity;

@Repository("entityOracleHibernateRepository")
public class EntityOracleHibernateRepository implements IBaseRepository {
	
	/**
	 * log4j日志记录
	 */
	protected static Logger logger = Logger.getLogger(EntityOracleHibernateRepository.class);
	
	protected <T extends IBaseEntity> void evictCollection(T entity){
		if(logger.isDebugEnabled()){
			logger.debug("执行BaseDao里面的evictCollection");
		}
	}

	@Inject
	@PersistenceContext(unitName="defaultOracle")
	public EntityManager entityManager;
	@Override
	public <T extends IBaseEntity> T get(Class<T> clazz, Serializable id) {
		return (T)entityManager.find(clazz, id);
	}
	@Override
	public <T extends IBaseEntity> T find(Class<T> clazz, Serializable id) {
		return (T)entityManager.getReference(clazz, id);
	}
	@Override
	public <T extends IBaseEntity> boolean exists(Class<T> clazz, Serializable id) {
		return get(clazz, id) != null;
	}
	@Override
	public <T extends IBaseEntity> List<T> findAll(Class<T> clazz) {
		String queryString = "select o from " + clazz.getName() + " as o";
		return entityManager.createQuery(queryString).getResultList();
	}
	@Override
	public <T extends IBaseEntity> void create(T o) {
		entityManager.persist(o);
		this.evictCollection(o);
	}
	@Override
	public <T extends IBaseEntity> void update(T o) {
		entityManager.merge(o);
		this.evictCollection(o);
	}
	@Override
	public <T extends IBaseEntity> void delete(Class<T> clazz, Serializable id) {
		this.delete(this.get(clazz, id));
	}
	@Override
	public <T extends IBaseEntity> void delete(T o) {
		entityManager.remove(o);
		this.evictCollection(o);
	}
	@Override
	public <T extends IBaseEntity> void save(T o) {
		if(o.getId()!=null){
			this.update(o);
		}else {
			this.create(o);
		}
	}
	@Override
	public <T extends IBaseEntity> void create(List<T> instances) {
		for(T t : instances){
			this.create(t);
		}
	}
	@Override
	public <T extends IBaseEntity> void update(List<T> instances) {
		for(T t : instances){
			this.update(t);
		}
	}
	@Override
	public <T extends IBaseEntity> void delete(List<T> instances) {
		for(T t : instances){
			this.delete(t);
		}
	}
	@Override
	public <T extends IBaseEntity> void save(List<T> instances) {
		for(T t : instances){
			this.save(t);
		}
	}
	/**
	 *  预编译hql查询
	 */
	public <T extends IBaseEntity > List<T> queryResult(final String queryStr, final Object[] params) {
		Query query = createQuery(queryStr, params);
		return query.getResultList();
	}
	
	/**
	 * 根据hql语句查询，支持分页
	 * @param queryStr
	 * @param params
	 * @param pageIndex  当前页码（从1开始）
	 * @param pageLen 每一页的长度（指每页显示多少条数据）
	 * @return
	 */
	public <T extends IBaseEntity > List<T> queryResult(final String queryStr, final Object[] params,int pageIndex,int pageLen) {
		Query query = createQuery(queryStr, params);
		int startIndex=(pageIndex-1)*pageLen;
		query.setFirstResult(startIndex);
		query.setMaxResults(pageLen);
		return query.getResultList();
	}
	@Override
	public Query createQuery(String hql, Object[] params) {
		Query query = entityManager.createQuery(hql);
		
		return setParameters(query, params);
	}
	
	private Query setParameters(Query query, Object[] params) {
		if (params != null) {
			for (int i = 0; i < params.length; i++) {
				query.setParameter(i + 1, params[i]);
			}
		}
		return query;
	}
}
